package tripx.siteget.crawler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import tripx.siteget.start.Client;
import tripx.update.City;
import tripx.update.Food;
import tripx.update.Site;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlParagraph;

public class CityCrawler {

	private String citySpell;

	private City city;

	private WebClient client;

	private ArrayList<String> siteList;

	public CityCrawler(String citySpell) {
		this.citySpell = citySpell;
		client = new WebClient(BrowserVersion.FIREFOX_17);
	}

	public void crawl() {
		String[] basicInfo = crawlBasic();
		String cityName = basicInfo[0];
		String intro = basicInfo[1];
		siteList = crawlSiteList();
		city = new City(cityName, intro);
		Client.getInstance().addCity(city);
	}

	private String[] crawlBasic() {
		// basicInfo[0]: city name
		// basicInfo[1]: city introduction
		String[] basicInfo = new String[2];
		try {
			HtmlPage page = client.getPage("http://lvyou.baidu.com/"
					+ citySpell);
			basicInfo[0] = ((HtmlParagraph) (page
					.getByXPath("//*[@id=\"body\"]/div/article/header/section[1]/header/p")
					.get(0))).getTextContent();
			String intro = "";
			HtmlParagraph introParagraph = (HtmlParagraph) page.getByXPath(
					"//*[@id=\"body\"]/div/article/header/section[2]/p").get(0);
			Iterable<DomNode> children = introParagraph.getChildren();
			for (DomNode node : children) {
				intro += (node.getTextContent().trim());
			}
			basicInfo[1] = intro;
		} catch (FailingHttpStatusCodeException | IOException e) {

		}
		return basicInfo;
	}

	private ArrayList<String> crawlSiteList() {
		ArrayList<String> siteList = new ArrayList<String>();
		try {
			HtmlPage page = client.getPage("http://lvyou.baidu.com/"
					+ citySpell + "/jingdian");
			getSiteListAt(page, siteList);
			while (true) {
				@SuppressWarnings("unchecked")
				List<HtmlAnchor> nextList = (List<HtmlAnchor>) page
						.getByXPath("//a[@class='tangram-pager-next']");
				if (nextList.size() == 0) {
					break;
				}
				HtmlAnchor next = nextList.get(0);
				HtmlPage nextPage = next.click();

				client.waitForBackgroundJavaScript(2000);

				getSiteListAt(nextPage, siteList);
				page = nextPage;
			}
		} catch (FailingHttpStatusCodeException | IOException e) {

		}
		return siteList;
	}

	private void getSiteListAt(HtmlPage page, ArrayList<String> siteList) {
		@SuppressWarnings("unchecked")
		List<HtmlDivision> divList = (List<HtmlDivision>) page
				.getByXPath("//div[@class='scene-pic-info']");
		for (HtmlDivision div : divList) {
			HtmlAnchor anc = div.getFirstByXPath("./p/a");
			siteList.add(anc.getHrefAttribute().replace('/', ' ').trim());
		}
	}

	public City getCity() {
		return city;
	}

	public void crawlSites() {
		// multi-thread
		for (final String siteSpell : siteList) {
			// new Thread(new Runnable() {
			//
			// @Override
			// public void run() {
			SiteCrawler crawler = new SiteCrawler(siteSpell, city.getCityName());
			crawler.crawl();
			Site site = crawler.getSite();
			Client.getInstance().addSite(site);
			// }
			//
			// }).start();
		}
	}

	public void crawFoods() {
		FoodCrawler crawler = new FoodCrawler(city.getCityName(), citySpell);
		crawler.crawl();
		ArrayList<Food> foodList = crawler.getFoodList();
		for (Food food : foodList) {
			Client.getInstance().addFood(food);
		}
	}
}
